バージョニングファイルと処理済みファイルをタグ付けしてS3 ライフサイクルポリシーで削除
はじめに
データアナリティクス事業本部ビッグデータチームのyosh-kです。
今回はS3 Bucketの不要なバージョニングファイルとdoneフォルダ(処理済みフォルダ)配下に移動したオブジェクトを特定の期間過ぎたら削除するライフサイクルポリシーの設定をやっていきたいと思います。
前提
今回処理対象のS3 フォルダ構成は以下になります。
前提としてS3 Bucketはバージョニングされているので、src配下のファイルをdone配下に移動した場合、src配下にはバージョニングされたファイルが残ります。今回削除したい要件としては、このsrc配下のバージョニングされたファイルとdoneに移動した処理済みオブジェクトになります。プロジェクトの要件によっては、何年かは過去データを保持する必要があると思いますが、そのままにしておくと永久にファイルは溜まり続けますので、一定の期間が経ったら削除する仕組みを導入したいです。
上記を実現するために、src配下のファイルをdone配下へ移動する処理の前後でそれぞれ別のタグを付与し、タグを条件としてS3 ライフサイクルポリシーで絞り込むことで削除することを実現したいと思います。ファイルの移動とタグ付けについては、以下ブログを参考にシェルスクリプトで実装を実現します。
シェルスクリプト実装
それでは実装になります。実装コードはリンクに格納しています。
@37_move_and_tag_deleting_with_lifecycle_policy % tree . ├── README.md └── move_put_tagging.sh 1 directory, 2 files @37_move_and_tag_deleting_with_lifecycle_policy %
#!/bin/bash # Move S3 Objects and put them tags. err() { echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $*" >&2 } function tag_object() { local bucket_name="$1" local object_key="$2" local tag_key="$3" local tag_value="$4" aws s3api put-object-tagging --bucket "$bucket_name" --key "$object_key" --profile "$PROFILE" \ --tagging "{\"TagSet\": [{\"Key\": \"$tag_key\", \"Value\": \"$tag_value\"}]}" || { err "Error: failed to put tag to $bucket_name/$object_key" return 1 } } echo "**********START $0 **********" if [ $# -ne 3 ]; then echo "引数が不正です。実行するには3個の引数が必要です。" >&2 echo "ex) sh move_put_tagging.sh s3://cm-kasama-life-cycle-test/src test_header.csv iam-role" >&2 err "スクリプトの実行に失敗しました。" exit 1 fi target=$1 DEST_DIR="done/" EXCLUDE_FILE="test.csv" EXCLUDE_FILE_HEADER=$2 OBJECT_DELETE_TAG_KEY="delete_marker_tag" OBJECT_DELETE_TAG_VALUE=true OBJECT_DONE_TAG_KEY="done_tag" OBJECT_DONE_TAG_VALUE=true PROFILE=$3 # 移動するファイルのURIリストを取得 TARGET_OBJECT_URIS="$(aws s3 mv "$target"/ "$target"/"$DEST_DIR" --profile "$PROFILE" --recursive --exclude "$EXCLUDE_FILE" \ --exclude "$EXCLUDE_FILE_HEADER" --exclude "${DEST_DIR}*" --dryrun | awk '{print $3}')" for uri in $TARGET_OBJECT_URIS; do bucket_name="$(echo "$uri" | cut -d '/' -f 3)" object_key="$(echo "$uri" | cut -d '/' -f 4-)" tag_object "$bucket_name" "$object_key" "$OBJECT_DELETE_TAG_KEY" "$OBJECT_DELETE_TAG_VALUE" done MOVED_OBJECT_URIS="$(aws s3 mv "$target"/ "$target"/"$DEST_DIR" \ --profile "$PROFILE" --recursive --exclude "$EXCLUDE_FILE" --exclude "$EXCLUDE_FILE_HEADER" \ --exclude "${DEST_DIR}*" --no-progress --output text | cut -d ' ' -f 4)" if [ $? -ne 0 ]; then # 警告(戻り値:2)の場合も通知する echo "エラー通知します。" 1>&2 err "次のファイル移動に失敗しました。 | ${target}" exit 1 fi echo "S3 objects have been successfully moved to: $target/$DEST_DIR" for uri in $MOVED_OBJECT_URIS; do bucket_name="$(echo "$uri" | cut -d '/' -f 3)" object_key="$(echo "$uri" | cut -d '/' -f 4-)" tag_object "$bucket_name" "$object_key" "$OBJECT_DONE_TAG_KEY" "$OBJECT_DONE_TAG_VALUE" done echo "**********SUCCESS $0 **********" exit 0
実装の要点については先ほど紹介したブログをご確認いただければと思います。ブログからの変更点としては、移動対象のオブジェクトに対して、移動前にタグを付与するために、aws s3 mv
コマンドに--dryrun
オプションを追加することで移動対象を抽出してタグを設定しています。
S3 ライフサイクルポリシー設定
次にS3 ライフサイクルポリシーを設定していきます。今回設定するのは3つになります。
done-tag-object-removal-rule
doneに移したオブジェクトを削除するライフサイクルルールになります。一定期間経過したら完全に削除されるように設定します。
- ライフサイクルルール名: done-tag-object-removal-rule
- フィルタータイプ:
- prefix: 未設定
- オブジェクトタグ:
- done_tag: true
- オブジェクトの現行バージョンを有効期限切れにする
- オブジェクト作成後の日数の指定:1日
- オブジェクトの非現行バージョンを完全に削除
- オブジェクトが現行バージョンでなくなってからの日数:1日
オブジェクトを現行バージョン作成後からN日後に有効期限切れにします。今回は検証用に1日と設定していますが、プロジェクトによって適切なデータ保持期間を設定いただければと思います。オブジェクトが非現行バージョンになってからは1日で削除するように設定しています。
delete-marker-tag-object-removal-rule
src配下のバージョニングされたオブジェクトを削除するライフサイクルルールになります。
- ライフサイクルルール名:delete-marker-tag-object-removal-rule
- フィルタータイプ:
- prefix: 未設定
- オブジェクトタグ:
- delete_marker_tag: true
- オブジェクトの非現行バージョンを完全に削除
- オブジェクトが現行バージョンでなくなってからの日数:1日
src直下のファイルがaws s3 mv
で移動されたことでバージョニングされたオブジェクトは非現行バージョンとなり、削除マーカーが現行バージョンとなります。そのため、本ルールで赤枠の非現行バージョンを削除するライフサイクルポリシーとなります。
expired-delete-marker-removal-rule
src配下の有効期限切れのオブジェクト削除マーカーを削除するライフサイクルルールになります。
- ライフサイクルルール名:expired-delete-marker-removal-rule
- フィルタータイプ:
- prefix: 未設定
- オブジェクトタグ:
- 未設定
- 有効期限切れのオブジェクト削除マーカーまたは不完全なマルチパートアップロードを削除
- 期限切れのオブジェクト削除マーカーを削除する
先ほどのdelete-marker-tag-object-removal-rule
で非現行バージョンは削除したので、現行バージョンが削除マーカーであるオブジェクトが残ります。このように過去バージョンが1つもない削除マーカーのことを有効期限切れオブジェクト削除マーカーと言います。画像赤枠の有効期限切れオブジェクト削除マーカーを削除することでオブジェクトを完全に削除します。この辺りの概念は以下資料もご確認いただければと思います。
実行結果
1日目
それでは実際に実行していきたいと思います。まずは、src配下にheader ファイルとdone移動対象の2つのcsvファイルを格納します。
処理対象のS3 Bucketへの操作権限を設定してあるIAM Roleをprofile引数に設定し、シェルスクリプトを実行します。 第一引数に移動したいオブジェクトが格納されているs3 path、第二引数は処理対象外のファイル名、第三引数にprofile名を指定します。
sh move_put_tagging.sh s3://cm-kasama-life-cycle-test/src test_header.csv <iam-profile>
2回バージョニングの処理が走り、問題なくmove処理が実行されていることを確認しました。
src配下では、test_1.csvとtest_2.csvは削除マーカーが付与されていること、delete_marker_tag
タグが付与されていることを確認しました。
done配下ではcsvファイルが現行バージョンとして存在し、done_tag
が付与されていることを確認しました。
2日目(17:00頃)
2日目以降は日本時間で考えると午前9時にオブジェクトの削除が処理される想定ですが、以下ブログにも言及がある通り、9時ちょうどに削除されるわけではないため、時間をおいて17時あたりに確認したいと思います。
src配下
変化無し。
done配下
変化無し。
3日目(17:00頃)
src配下
非現行バージョンオブジェクトが削除されていることを確認しました。
done配下
オブジェクトが現行バージョンから有効期限切れになったことがわかります。
バージョンの表示を設定しない場合は、オブジェクトが消えていることがわかります。
4日目(17:00頃)
src配下
3日目から変化無し。
done配下
3日目から変化無し。
5日目(17:00頃)
src配下
有効期限切れオブジェクト削除マーカーが削除された状態になりました。
done配下
3日目から変化無し。
6日目(17:00頃)
done配下
非現行バージョンオブジェクトが削除されていることを確認しました。
7日目(17:00頃)
done配下
有効期限切れオブジェクト削除マーカーが削除され、全て空になりました。
まとめ
結果をまとめると以下のようになりました。src配下と比較してdone配下の非現行バージョンオブジェクト削除から有効期限切れオブジェクト削除マーカー削除に1日の空きがないので、確認する時間によっては結果が変わっていたかもしれませんが、実現したいことは確認できたので検証は正常終了とします。
日付 | src配下の状態 | done配下の状態 |
---|---|---|
1日目 | 移動したオブジェクトに削除マーカーとdelete_marker_tagタグ付与 | オブジェクトが現行バージョンとして存在、done_tagタグ付与 |
2日目 | 変化無し | 変化無し |
3日目 | 非現行バージョンオブジェクト削除 | オブジェクトが現行バージョンから有効期限切れに |
4日目 | 3日目から変化無し | 3日目から変化無し |
5日目 | 有効期限切れオブジェクト削除マーカー削除 | 3日目から変化無し |
6日目 | ー | 非現行バージョンオブジェクト削除 |
7日目 | ー | 有効期限切れオブジェクト削除マーカー削除 |
最後に
今回はS3ライフサイクルポリシーでの削除を設定しましたが、システムによっては永久保存であることもあります。そのような場合は削除ではなくS3 ストレージクラスの変更を設定するとコスト削減につながると思います。このブログが少しでもどなたかのお役に立てれば幸いです!